#include<iostream>
#include<string>
#include<cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<jsoncpp/json/json.h>

using namespace std;

#define SEP " "
#define SEP_LEN strlen(SEP)
#define SEP_LINE "\r\n"
#define SEP_LINE_LEN strlen(SEP_LINE)


string enlength(string &message)
{ string m;
  m+=to_string(message.size());
  m+=SEP_LINE;
  m+=message;
  m+=SEP_LINE;
  return m;

}
bool delength(string &message,string *in)
{  
     auto pos=message.find(SEP_LINE);
     if(pos==string::npos) return false;
     int text_len=stoi(message.substr(0,pos));
     *in=message.substr(pos+SEP_LINE_LEN,text_len);
     return true;


}
class request
{ public:
  request(int x,int y,char op):_x(x),_y(y),_op(op)
  {    
  }
  request():_x(0),_y(0),_op(0)
  {}
  bool serialize(string *out)
  { 
    
  #ifdef MYSELF
    *out+=to_string(_x);
    *out+=SEP;
    *out+=_op;
    *out+=SEP;
    *out+=to_string(_y);
    
    //*out+=SEP_LINE;
  #else
      Json::Value root;
      root["first"]=_x;
      root["second"]=_y;
      root["oper"]=_op;
      Json::FastWriter writer;
      *out=writer.write(root);

  #endif
    return true;
  }
  bool deserialize(const string &message)
  {  
  #ifdef MYSELF
    auto left=message.find(SEP);
      auto right=message.rfind(SEP);
       if (left == string::npos || right == string::npos || left == right)
        return false;
     string x_string=message.substr(0,left);
     string y_string=message.substr(right + SEP_LEN);//错误点是加错步长，不加后缀，可以直接从字符开始切割
     if(x_string.empty()||y_string.empty()) return false;
     _x=stoi(x_string);
     _y=stoi(y_string);
     _op=message[left+SEP_LEN];
  #else
     Json::Value root;
     Json::Reader reader;
     reader.parse(message,root); 
     _x=root["first"].asInt();
     _y=root["second"].asInt();
     _op=root["oper"].asInt();




  #endif
     return true;
  }
 
   

public:
int _x;
int _y;
char _op;

};


class response
{public:
   response():result(0),exitcode(0){}
   bool serialize(string *out)
   {
#ifdef MYSELF
    *out+=to_string(result);
    *out+=SEP;
    *out+=to_string(exitcode);
#else
     Json::Value root;
     root["ex"]=exitcode;
     root["re"]=result;
     Json::FastWriter writer;
     *out=writer.write(root);

#endif
      return true;
   }
   bool deserialize(const string &in)
   {  
#ifdef MYSELF
    auto pos=in.find(SEP);
     if(pos==string::npos)return false;
     string res_string=in.substr(0,pos);
     string ec_string=in.substr(pos+SEP_LEN);
      result=stoi(res_string);
      exitcode=stoi(ec_string);
#else
       Json::Value root;
       Json::Reader reader;
       reader.parse(in,root);
       exitcode=root["ex"].asInt();
       result=root["re"].asInt();



#endif


      return true;
   }
    

public:
  int result;
  int exitcode;
   
};

bool recvmessage(int sock,string*in,string*inbuffer)
{  
  while(true)
  { char buffer[1024];
     ssize_t n=recv(sock,buffer,sizeof(buffer),0);//这行代码中 inbuffer 是 string* 类型，不能直接作为缓冲区使用
    
    if(n>0)
    {  buffer[n]=0;
      *inbuffer+=buffer;
      
      auto pos =inbuffer->find(SEP_LINE);
      if(pos==string::npos) continue;//说明一个完整的长度字符都没读到
      int text_len=stoi(inbuffer->substr(0,pos));
      string pre=inbuffer->substr(0,pos);
      int all_len=pre.size()+text_len+2*SEP_LINE_LEN;
      if(inbuffer->size()<all_len)
      {std::cout << "你输入的消息，没有严格遵守我们的协议，正在等待后续的内容, continue" << std::endl;
        continue;
      }
      *in=inbuffer->substr(0,all_len);
      inbuffer->erase(0,all_len);
      std::cout << "处理后#inbuffer:\n " << inbuffer << std::endl;
      break;
    }
    else
    {
      break;
      return false;
    }

  }
  
 return true;
}
